/*
    代码有些地方不是很合理，不过由于时间比较赶，结果是正确的也就没有再做调整
    后期建议根据业务重新开发，谢谢
    write by lei.jiangl
*/
var https = require('https');
//var sqlite3 = require('sqlite3').verbose();
var querystring = require('querystring');
var ET = require('elementtree');
///var db = new sqlite3.Database('/Users/jiangleivos/alibaba-work/DB/db');
//var $ = require('jquery');
var fs = require('fs');
var idx = 1;
// var workSpace = '/Users/jiangleivos/alibaba-work'
var workSpace = '/home/pts/alibaba-work/'
var timeNow = new Date();
// var tableName = 'test_Id';
// ET.register_namespace('soapenv', 'http://schemas.xmlsoap.org/soap/envelope/');
// ET.register_namespace('v201', 'https://adwords.google.com/api/adwords/cm/v201302');
// ET.register_namespace('v20', 'https://adwords.google.com/api/adwords/o/v201302');


var SOAP = {
    'soapenv': 'http://schemas.xmlsoap.org/soap/envelope/',
    'ns_xsd': 'http://www.w3.org/1999/XMLSchema',
    'ns_xsi': 'http://www.w3.org/2001/XMLSchema-instance',
    'ns_soapenc': 'http://schemas.xmlsoap.org/soap/encoding/',
    'v201': 'https://adwords.google.com/api/adwords/cm/v201302',
    'v20': 'https://adwords.google.com/api/adwords/o/v201302'
};

var path = workSpace+'/report/report/keywordStats/';
var rstPath = workSpace+'/report/report/targetStatsResult/';
var arg1 = process.argv[2] || 0;
var arg2 = process.argv[3] || 0;

function getToken(callback) {
    // console.log('-----------------------------------------------------getToken');
    logTime('getToken start');
    var qstr = querystring.stringify({
        Email: 'ptapitest@gmail.com',
        Passwd: 'aA123456',
        accountType: 'GOOGLE',
        source: 'adwords-tutorial',
        service: 'adwords'
    });
    // console.log(qstr);
    var sconf = {
        host: 'www.google.com',
        // host:'74.125.128.147',
        path: '/accounts/ClientLogin' + '?' + qstr,
        method: 'GET',
        headers: {}
    };
    var req = https.request(sconf, function(res) {
        // console.log(res);
        res.on('data', function(data) {
            var t = data.toString().split('\n')[2];
            var token = t.split('Auth=')[1];
            logTime('getToken end');
            callback(token);
        });

    })
    req.end();
}


function sendSOAP(xml, callback) {
    // console.log('-----------------------------------------------------sendSOAP');
    logTime('sendSOAP start');

    var soapStr = toXMLString.call(xml);
    var conf = {
        host: 'adwords.google.com',
        // host:'74.125.128.51',
        method: 'POST',
        header: {
            // 'Accept-Encoding': 'gzip,deflate',
            'Content-Type': 'text/xml;charset=UTF-8',
            'Content-Length': soapStr.length
        },
        path: '/api/adwords/o/v201302/TargetingIdeaService?wsdl'
    }
    var req = https.request(conf, function(res) {
        var dataStr = '';
        logTime('res.statusCode=' + res.statusCode);
        // if(res.statusCode === 500) {
        //     console.log(res);
        // }
        // console.log('===============================', res.statusCode);
        res.on('end', function() {
            // console.log(dataStr);
            logTime('sendSOAP end');
            if (res.statusCode === 500) {
                if (dataStr.indexOf('RateExceededError') != -1) {
                    sendSOAP(xml, callback);
                }

                console.log(soapStr);
                console.log(dataStr);
            } else {
                callback(dataStr);
            }

        })
        var count = 0;
        res.on('data', function(data) {
            dataStr += data.toString();
        });

    });
    // console.log('+++++++++++++++++++++++++++++++\n',soapStr)
    req.write(soapStr);
    req.end();
}

function getKeywordMap(path) {
    var fileArr = [],
        keywordMap = {};
    var files = fs.readdirSync(path);
    files.forEach(function(name) {
        if (name.split('.')[0] !== '') {
            fileArr.push(name);
        }
    })

    fileArr.forEach(function(fileName) { //遍历读取文件夹下所有文件
        var data = fs.readFileSync(path + fileName, 'utf-8');
        // console.log(data);
        var fa = data.toString().split('\n');
        if(fa[fa.length-1]===''){
            fa.pop();
        }
        keywordMap[fileName] = [];
        // console.log(keywordMap);
        fa.forEach(function(keyword) {
            if (keyword !== '') {
                keywordMap[fileName].push(keyword);
                // console.log(keyword);
            }
        });
        console.log('loading file name', fileName);
    })
    // console.log(keywordMap);
    return keywordMap;
}

function getGoogleData(xml, keywordMap) {
    // return;
    logTime('getGoogleData start');
    var kIndex = 0,
        keywordIdx = 0;
    // console.log(xml);
    var keywordEstimate = xml.find('.//v20:keywordEstimateRequests');
    var keywordEstimate = ET.Element('v20:keywordEstimateRequests');
    var searchParameters = xml.find('.//v20:searchParameters');
    // console.log(keywordMap);
    var keyArr = [];
    for (var k in keywordMap) {
        keyArr.push(k);
    }
    function _getGoolgeData(kIndex, keywordIdx, callback) {
        // return;
        // console.log(kIndex,keywordIdx);
        var step = 2500;
        var key = keyArr[kIndex];
        // keywordIdx=keywordIdx>keywordMap[key].length-1?keywordMap[key].length-1:keywordIdx
        var keyword = keywordMap[key][keywordIdx];
        logTime(kIndex + '  ' + keywordIdx + '  ' + key + '   begin');
        searchParameters.clear();
        // return;
        searchParameters.set('ns_xsi:type', 'v20:RelatedToQuerySearchParameter');
        //去重
        var discArr = [],
            discMap = {};
        //一次请求2500个词
        if (keywordMap[key].length - 1 - keywordIdx <= step) {
            step = keywordMap[key].length - 1 - keywordIdx;
        }
        // console.log('step=',step);
        var i = 0;
        // console.log(keywordMap[key].length);
        do {
            var discKeyword = keywordMap[key][keywordIdx + i];
            if(discMap[discKeyword]==undefined){
                discMap[discKeyword] = '';
            }
        } while (++i < step);
        for (var k in discMap) {
            discArr.push(k);
        }
        // console.log(discArr);
        discArr.forEach(function(keyword) {
            var query = ET.Element('{' + SOAP['v20'] + '}queries');
            // query.text = escape(keyword);
            query.text = keyword;
            // logTime(query.text);
            searchParameters.append(query);
        });
        // console.log('discArr.length',discArr.length);
        // return;
        sendSOAP(xml, function(xmlStr) { //发送soap请求
            var x = ET.XML(xmlStr);
            var entries = x.findall('.//entries');
            var keywordArr = [];
            var valueArr = [];
            var cmptArr = []
            entries.forEach(function(entry) {
                var datas = entry.findall('.//data');
                datas.forEach(function(data) {
                    var value = 0;
                    var cmpt = 0;
                    // console.log(data)
                    var k = data.find('./key').text;
                    switch (k) {
                        case 'KEYWORD_TEXT':
                            var keyword = data.find('./value/value').text;
                            // keywordArr.push(unescape(keyword));
                            keywordArr.push(keyword);
                            break;
                        case 'SEARCH_VOLUME':
                            if (data.find('./value/value')) {
                                value = data.find('./value/value').text;
                            }
                            valueArr.push(value);
                            break;
                        case 'COMPETITION':
                            if (data.find('./value/value')) {
                                cmpt = data.find('./value/value').text;
                            }
                            cmptArr.push(cmpt);
                            break;
                    }
                })
            });
            // console.log(keywordArr.length,valueArr.length);
            writeFile(key, keywordArr, valueArr, cmptArr); //按照业务逻辑写文件

            logTime(kIndex + '  ' + keywordIdx + '  ' + key + '   end');
            if (keywordIdx < keywordMap[key].length - 1) {
                // keywordIdx ++;
                keywordIdx += step;
                setTimeout(function() {
                    callback(kIndex, keywordIdx, _getGoolgeData);
                }, 1000)
            } else {
                keywordIdx = 0;
                if (kIndex < keyArr.length - 1) {
                    kIndex++;
                    setTimeout(function() {
                        // body...
                        callback(kIndex, keywordIdx, _getGoolgeData);
                    }, 1000)
                }
            }

            // console.log(x);
        });
    }
    _getGoolgeData(parseInt(arg1), parseInt(arg2), _getGoolgeData);
    // logTime('getGoogleData end');
}

function writeFile(fileName, keywordArr, valueArr, cmptArr) {
    var _path = rstPath + fileName.split('.')[0] + '_targetStats.txt';
    var str = '';
    for (var i = 0; i < keywordArr.length; i++) {
        // if(checkKeyword(keywordArr[i],valueArr[i])){
        str += keywordArr[i] + ',' + valueArr[i] + ',' + cmptArr[i] + '\r\n';
        // }
    }
    fs.appendFileSync(_path, str);
}

function main() {
    var keywordMap = getKeywordMap(path);
    logTime('main ' + timeNow);
    var str = fs.readFileSync('../soapXML/googleTargetingStats.xml').toString();
    var xml = ET.XML(str);
    getGoogleData(xml, keywordMap);
    return;
    getToken(function(AuthToken) {
        console.log('-----------------------------------------------------getToken')
        xml.find('.//v201:authToken').text = AuthToken;
        getGoogleData(xml, keywordMap);

    });
}

function toXMLString() {
    return ET.tostring(this, {
        xml_declaration: false
    });
}

function logTime(str) {
    console.log('----------------------------------------------------- ' + str + '   ', (new Date().getTime() - timeNow.getTime()) / 1000 + 'S');
}
main();
